起因
其实我不想写起因,一位面试人家让我写一个套接字,不会,输入输出,不会写。唉。。。 写代码吧,现在想想,我认真写java代码也没多久,慢慢来呗;
套接字
这个怎么理解呢,就是说tcp/udp在运输层,那么上层好多应用都要使用TCP,那么怎么区分呢?这时候就出现了套接字和端口,应用程序自己创建套接字,标记自己的端口,那么分包的时候就有了约束,传回的数据包,也可以根据端口找到位置;代码传送门
Demo时间
下面会有很多Demo 主要参考了 参考一,参考二,主要参考;
Demo1
客户端获取服务器发过来的信息,然后就完了;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public class TestClient { public static void main(String args[]) { try { Socket s1 = new Socket("127.0.0.1", 8888); InputStream is = s1.getInputStream(); DataInputStream dis = new DataInputStream(is); System.out.println(dis.readUTF()); System.out.println(dis.readUTF()); dis.close(); s1.close(); } catch (IOException e) { e.printStackTrace(); } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public class TestServer { public static void main(String args[]) { try { ServerSocket s = new ServerSocket(8888); while (true) { Socket socket = s.accept(); OutputStream os = socket.getOutputStream(); DataOutputStream dos = new DataOutputStream(os); dos.writeUTF("你好,客户端地址信息: " + socket.getInetAddress() + "\t客户端通信端口号: " + socket.getPort()); dos.writeUTF("i'm a server ,my name is colin!"); dos.close(); socket.close(); } } catch (IOException e) { e.printStackTrace(); } } }
|
题外话:
我们很容易服务器和客户端的形式基本类似这样:
1 2 3 4 5 6 7 8
| ServerSocket s = new ServerSocket(8888); while (true) { Socket socket = s.accept(); */ */ }
|
socket如果接收不到,服务器就会就等着;
将其放在while(true)中,就一直监听;上一个关掉,监听下一个;
1
| Socket socket = s.accept();
|
对于流来说,这里就很麻烦,一会儿就被绕晕了;输入,输出到底是针对谁来说的呢?
首先我们要清楚读和写;很简单吧,正因为简单,所以我就被弄糊涂了;
考虑我们在纸上写字;我们就将其简化为写;
然后我们抄写一遍,我们就需要先读出来,然后在写下;
这里我们会很容易想到我们写,我们读的;主题对象是我们;
但是考虑我们现在在敲代码;写是肯定的。但是真的在写吗?这是一个问题啊;我们通过键盘输入一段字符,字节流,给了机器,很明显的输入流对比,但是对系统来说,他是读的啊,他得知道你敲了啥啊;
所以输入流是这样一种对象: 读入你的输入,并且已相应的的格式,编码读给系统; 举个例子,大家来学校报道,报道通道相当于一个输入流,不断地来人,报道哪里会有人看你的档案,哦,你叫张三,然后学校知道你叫做张三;这就是输入流做的事情;
翻过来输出流,相当于什么呢?大家毕业了,排着队去照毕业照;不断地人流,到了照相馆照相;咔咔咔,大家就被输出了;这样不生动,我们换成劳动力市场,学校作为主体,输入流就是毕业时一个一个下发的档案,然后大家就可以去找工作了;学校就不管你了,你被输出了;
DEMO2
客户端一直说,服务器一直听;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| public class Client { Socket client; public Client() { try { client = new Socket("localhost", 7777); OutputStream outputStream = client.getOutputStream(); DataOutputStream dataOutputStream = new DataOutputStream(outputStream); InputStreamReader inputStreamReader = new InputStreamReader(System.in); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String a; while (true) { a = bufferedReader.readLine(); if (a.equals("bye")) break; dataOutputStream.writeUTF(a); } dataOutputStream.close(); bufferedReader.close(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { new Client(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public class Server { private Socket socket; private ServerSocket ss; public Server() throws IOException { ss = new ServerSocket(7777); socket = ss.accept(); InputStream inputStream = socket.getInputStream(); DataInputStream dataInputStream = new DataInputStream(inputStream); while (true) { String a = dataInputStream.readUTF(); if (a.equals("bye")) break; System.out.println(a); br.readLine()); } } public static void main(String[] args) { try { new Server(); } catch (IOException e) { e.printStackTrace(); } } }
|
在这里我们发现一个socket一边写,一边读,像不像是只是一个文件呢?
Demo3
客户端和服务器必须一人一句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| public class TestClient { public static void main(String[] args) { try { Socket socket = new Socket("localhost",8888); OutputStream outputStream = socket.getOutputStream(); DataOutputStream dataOutputStream = new DataOutputStream(outputStream); InputStream inputStream = socket.getInputStream(); DataInputStream dataInputStream = new DataInputStream(inputStream); InputStreamReader inputStreamReader = new InputStreamReader(System.in); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String info; String info1; while (true) { info = bufferedReader.readLine(); dataOutputStream.writeUTF(info); if (info == "bye") break; info1 = dataInputStream.readUTF(); System.out.println("服务器"+info1); if (info1 == "bye") break; } bufferedReader.close(); dataInputStream.close(); dataOutputStream.close(); socket.close(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| public class TestServer { public static void main(String[] args) { try { ServerSocket serverSocket = new ServerSocket(8888); Socket socket = serverSocket.accept(); OutputStream outputStream = socket.getOutputStream(); DataOutputStream dataOutputStream = new DataOutputStream(outputStream); InputStream inputStream = socket.getInputStream(); DataInputStream dataInputStream = new DataInputStream(inputStream); InputStreamReader inputStreamReader = new InputStreamReader(System.in); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String info; String info1; while (true) { info = dataInputStream.readUTF(); System.out.println("客户端说:"+ info); if (info.equals("bye")) break; info1 = bufferedReader.readLine(); dataOutputStream.writeUTF(info1); if (info1.equals("bye")) break; } dataInputStream.close(); dataOutputStream.close(); bufferedReader.close(); socket.close(); serverSocket.close(); } catch (SocketException e) { System.out.println("网络异常"); } catch (IOException e) { e.printStackTrace(); } } }
|
其实这里我们就发现,这其实就是典型的一个TCP的连接了,一个一直监听,一个需要找到正确的ip和端口,才能正确获得socket;
Demo4
其实就是两个线程,一个读,一个写;像不像一个棉花,可以随时咬一口,或者随时放一块;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| public class TestClient { public static void main(String[] args) { try { Socket socket = new Socket("localhost",8888); InputStream inputStream = socket.getInputStream(); DataInputStream dataInputStream = new DataInputStream(inputStream); OutputStream outputStream = socket.getOutputStream(); DataOutputStream dataOutputStream = new DataOutputStream(outputStream); new MyClientReader(dataInputStream).start(); new MyClientWriter(dataOutputStream).start(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } class MyClientReader extends Thread{ private DataInputStream dataInputStream; public MyClientReader(DataInputStream dataInputStream) { this.dataInputStream = dataInputStream; } @Override public void run() { String info; try { while (true) { info = dataInputStream.readUTF(); System.out.println("服务器说:"+info); if (info.equals("bye")){ System.out.println("对方不想理你了"); System.exit(0); } } } catch (IOException e) { System.out.println("服务器死翘翘了"); e.printStackTrace(); } } } class MyClientWriter extends Thread { private DataOutputStream dataOutputStream; public MyClientWriter(DataOutputStream dataOutputStream) { this.dataOutputStream = dataOutputStream; } @Override public void run() { InputStreamReader inputStreamReader = new InputStreamReader(System.in); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String info; try { while (true) { info = bufferedReader.readLine(); dataOutputStream.writeUTF(info); if (info.equals("bye")) { System.out.println("感谢使用"); System.exit(0); } } } catch (IOException e) { e.printStackTrace(); } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| public class TestServer { public static void main(String[] args) { try { ServerSocket serverSocket = new ServerSocket(8888); Socket socket = serverSocket.accept(); OutputStream outputStream = socket.getOutputStream(); DataOutputStream dataOutputStream = new DataOutputStream(outputStream); InputStream inputStream = socket.getInputStream(); DataInputStream dataInputStream = new DataInputStream(inputStream); new MyClientReader(dataInputStream).start(); new MyServerWriter(dataOutputStream).start(); } catch (IOException e) { e.printStackTrace(); } } } class MyServerReader extends Thread{ private DataInputStream dataInputStream; public MyServerReader(DataInputStream dataInputStream) { this.dataInputStream = dataInputStream; } @Override public void run() { String info; try { while (true) { info = dataInputStream.readUTF(); System.out.println("客户端说"+info); if (info.equals("bye")){ System.out.println("对方不想理你了"); System.exit(0); } } } catch (IOException e) { e.printStackTrace(); } } } class MyServerWriter extends Thread { private DataOutputStream dataOutputStream; public MyServerWriter(DataOutputStream dataOutputStream) { this.dataOutputStream = dataOutputStream; } @Override public void run() { InputStreamReader inputStreamReader = new InputStreamReader(System.in); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String info; try { while (true) { info = bufferedReader.readLine(); dataOutputStream.writeUTF(info); if (info.equals("bye")) { System.out.println("感谢使用"); System.exit(0); } } } catch (IOException e) { e.printStackTrace(); } } }
|
总结
- 其实一位套接字是很难的东西,学下来,感觉还是很容易理解的;
- 加油努力吧!